import {_decorator, error, instantiate, JsonAsset, Node, Prefab, resources, TextAsset} from "cc";
import {DeviceUtil} from "./DeviceUtil";
import {BaseRouteConstants} from "../constant/BaseRouteConstants";

const {ccclass} = _decorator;

@ccclass("ResourceUtil")
export class ResourceUtil {
    /**
     * 加载资源
     * @param url   资源路径
     * @param type  资源类型 cc.Texture2D cc.SpriteFrame cc.SpriteAtlas cc.Prefab
     *              加载 SpriteAtlas（图集），并且获取其中的一个 SpriteFrame, 注意 atlas 资源文件（plist）通常会和一个同名的图片文件（png）放在一个目录下, 所以需要在第二个参数指定资源类型
     * @param cb    回调
     * @method loadRes
     */
    public static loadRes(url: string, type: any, cb: Function) {
        resources.load(url, type, (err: any, res: any) => {
                if (err) {
                    // error(err.message || err);
                    cb(err, res);
                    return;
                }

                cb && cb(null, res);
            }
        )
    }

    /**
     * 加载目录资源
     * @param url   资源路径
     * @param type  资源类型 cc.Texture2D cc.SpriteFrame cc.SpriteAtlas cc.Prefab
     *              加载 SpriteAtlas（图集），并且获取其中的一个 SpriteFrame, 注意 atlas 资源文件（plist）通常会和一个同名的图片文件（png）放在一个目录下, 所以需要在第二个参数指定资源类型
     * @param cb    回调
     * @method loadRes
     */
    public static loadDirRes(url: string, type: any, cb: Function) {
        resources.loadDir(url, type, (err: any, res: any) => {
            if (err) {
                // error(err.message || err);
                cb(err, res);
                return;
            }

            cb && cb(null, res);
        })
    }


    /**
     * 图片设置为 sprte-frame或 texture 或其他图片类型后，将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 test asets/image，
     * 得到的类型将会ImageAsset 。你必须指定路径到具体的子资源，才能加载到图片生成的 SpriteFrame :
     * 加载资源：加载 SpriteFrame， image 是 ImageAsset, spriteFrame 是 image/spriteFrame，texture 是 image/texture
     * @param url   资源路径
     * @param type  资源类型
     * @method loadRes
     */
    public static loadResType(url: string, type: any) {
        return new Promise((resolve, reject) => {
            resources.load(url, type, (err: any, res: any) => {
                if (err) {
                    error(err.message || err);
                    reject && reject(err)
                    return;
                }

                resolve && resolve(res);
            })
        })
    }

    /**
     * 加载预制体资源
     * @param prefPath 路径
     * @returns
     */
    public static loadPrefabRes(prefPath: string) {
        return new Promise((resolve, reject) => {
            this.loadRes(prefPath, Prefab, (err: any, prefab: Prefab) => {
                if (err) {
                    console.error('prefab load failed：', prefPath);
                    reject && reject();
                    return;
                }

                resolve && resolve(prefab);
            })
        })
    }

    /**
     * 批量加载多模型数据
     * @param pathPrefix 资源路径
     * @param resNames 资源名称
     * @param progressCb 过程回调函数
     * @param completeCb 完成回调函数
     */
    public static batchLoadRes(pathPrefix: string, resNames: Array<string>, progressCb: any, completeCb: any) {
        let arrUrls = resNames.map((item) => {
            return `${pathPrefix}/${item}`;
        })

        resources.load(arrUrls, Prefab, progressCb, completeCb);
    }

    /**
     * 获取UI prefab
     * @param prefabPath prefab路径
     * @param cb 回调函数
     */
    public static getUIPrefabRes(prefabPath: string, cb?: Function) {
        this.loadRes(prefabPath, Prefab, cb);
    }

    /**
     * 创建ui界面
     * @param path ui路径
     * @param cb 回调函数
     */
    public static createUI(path: string, cb?: Function) {
        this.getUIPrefabRes(path, function (err: {}, prefab: Prefab) {
            if (err) return;
            let node: Node = instantiate(prefab);
            node.setPosition(DeviceUtil.getViewWidth() / 2, DeviceUtil.getViewHeight() / 2, 0);
            cb && cb(null, node);
        });
    }

    /**
     * 获取json数据
     * @param fileName 文件名
     * @param cb 回调函数
     */
    public static getJsonData(fileName: string, cb: Function) {
        this.loadRes(fileName, null, function (err: any, content: JsonAsset) {
            if (err) {
                error(err.message || err);
                return;
            }

            if (content.json) {
                cb(err, content.json);
            } else {
                cb('failed!!!');
            }
        });
    }

    /**
     * 获取文本数据
     * @param fileName 文件名
     * @param cb  回调函数
     */
    public static getTextData(fileName: string, cb: Function) {
        this.loadRes(fileName, null, function (err: any, content: TextAsset) {
            if (err) {
                error(err.message || err);
                return;
            }

            let text: string = content.text;
            cb(err, text);
        });
    }
}
